﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SocketControl.Protocol.Http.Event;
using System.IO;

namespace SocketControl.Protocol.Http
{
    public class Http : Ihttp
    {
        public event EventHandler<HttpEventArgs> GetBodyCompleted;

        /// <summary>
        /// 数据缓存
        /// </summary>
        protected MemoryStream readStream = null;

        /// <summary>
        /// 读取Response头完成
        /// </summary>
        protected EventHandler<HttpEventArgs> ReadResponseRealy;

        /// <summary>
        /// 读取Response头成功标志
        /// </summary>
        protected bool readResponseRealy = false;

        /// <summary>
        /// Response头偏移量
        /// </summary>
        protected int httpResponseOffset = 0;

        /// <summary>
        /// 数据块大小；
        /// </summary>
        protected int dataSize = 0;

        /// <summary>
        /// chunked偏移量
        /// </summary>
        protected int chunkedOffest = 0;

        protected int pos = 0;

        protected ResponseMessage.IResponse response = new ResponseMessage.Response();
        protected Model.Response responseModel = new Model.Response();

        public Http()
        {
            this.ReadResponseRealy += new EventHandler<HttpEventArgs>(EventReadResponseRealy);
        }

        #region event listen

        protected void EventReadResponseRealy(object sender, HttpEventArgs args)
        {
            if (readResponseRealy)
            {
                if (responseModel != null)
                {
                    TransferType(responseModel);
                }
            }
        }


        protected void TransferType(Model.Response response)
        {

            if (responseModel.Transfer_Encoding != null)
            {
                //todo Chunked Data Transfer
                GetChunkedData chunked = new GetChunkedData();
                Byte[] param = new byte[((int)this.readStream.Length - this.httpResponseOffset)];
                Array.Copy(this.readStream.GetBuffer(), this.httpResponseOffset, param, 0, ((int)this.readStream.Length - this.httpResponseOffset));

                chunked.GetChunkedSize(this, param);
            }
            else
            {
                //todo Genernal Data Transfer
                ;
            }
        }

        #endregion

        private void ReadResponse()
        {
            byte[] param =
            #region getHttpResponse
            int offset = 0;
            for (offset = 0; offset < param.Length; offset++)
            {
                ++httpResponseOffset;
                if (offset >= 3)
                {
                    if (param[offset - 3] == 13 && param[offset - 2] == 10 && param[offset - 1] == 13 && param[offset] == 10)
                    {
                        byte[] httpBuff = new byte[httpResponseOffset];
                        Array.Copy(readStream.GetBuffer(), 0, httpBuff, 0, httpResponseOffset);
                        responseModel = response.GetInstance(Encoding.UTF8.GetString(httpBuff));
                        readResponseRealy = true;
                        GetData(param);
                        break;
                    }
                }
            }
            if (readResponseRealy)
            {
                GetData(param);
            }
            #endregion
        }

        public void GetData(byte[] param)
        {
            if (readStream == null)
            {
                readStream = new MemoryStream();
            }
            this.readStream.Write(param, 0, param.Length);
            if (!this.readResponseRealy)
            {
                ReadResponse();
            }
            else
            {
                TransferType(this.responseModel);
            }
        }
    }
}
